package taskTracker.ui.lite;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.TextField;

import taskTracker.util.Helper;
import taskTracker.util.Setting;

/**
 * Displays settings of one category to the user to be edited
 * @author aseldawy
 *
 */
public class SettingsPage extends Form {
	
	private Command cmdBack = new Command("Back", Command.BACK, 1);
	private Setting[] settings;
	
	/**
	 * Maps each UI item to its setting
	 */
	private Hashtable item2Setting = new Hashtable();

	public SettingsPage(String category, Setting[] settings) {
		super(category);
		for (int i = 0; i < settings.length; i++) {
			if (settings[i].category.equals(category)) {
				Item item = createItem(settings[i]);
				if (item != null) {
					super.append(item);
					item2Setting.put(item, settings[i]);
				}
			}
		}
		this.settings = settings;
		super.addCommand(cmdBack);
	}

	/**
	 * Create a UI item appropriate to view and edit the given setting.
	 * @param setting
	 * @return
	 */
	private Item createItem(Setting setting) {
		if (setting.type == "hidden") {
			return null;
		} else if (setting.type == "String") {
			return new TextField(setting.name, (String) setting.value, 1024,
					TextField.ANY);
		} else if (setting.type == "Integer") {
			return new TextField(setting.name, ((Integer) setting.value)
					.toString(), 1024, TextField.NUMERIC);
		} else if (setting.type == "Boolean") {
			ChoiceGroup cg = new ChoiceGroup("", ChoiceGroup.MULTIPLE);
			cg.append((Object)setting.name, null);
			cg.setSelectedIndex(0, ((Boolean)setting.value).booleanValue());
			return cg;
		} else if (setting.type.startsWith("multiple\n")) {
			ChoiceGroup cg = new ChoiceGroup(setting.name, ChoiceGroup.POPUP);
			String[] parts = Helper.split(setting.type, "\n");
			for (int i = 1; i < parts.length; i++) {
				cg.append((Object)parts[i], null);
			}
			cg.setselectedObject(setting.value);
			return cg;
		} else {
			throw new RuntimeException("Cannot create a UI to edit the setting: "+setting+" of type: "+setting.type);
		}
	}
	
	/**
	 * Retrieves user entered value for the given property
	 * @param item
	 * @param setting
	 * @return
	 */
	private Object getItemValue(Item item, Setting setting) {
		if (setting.type == "String") {
			return ((TextField)item).getString();
		} else if (setting.type == "Integer") {
			return new Integer(Integer.parseInt(((TextField)item).getString()));
		} else if (setting.type == "Boolean") {
			boolean[] selectedFlags = new boolean[1];
			((ChoiceGroup)item).getSelectedFlags(selectedFlags);
			return new Boolean(selectedFlags[0]);
		} else if (setting.type.startsWith("multiple\n")) {
			return (String)(((ChoiceGroup)item).getSelectedObject());
		} else {
			throw new RuntimeException("Cannot retrieve UI value: "+setting+" of type: "+setting.type);
		}
	}
	
	/**
	 * Apply user choices to settings array
	 */
	public void applySettings() {
		for (Enumeration e = item2Setting.keys(); e.hasMoreElements();) {
			Item item = (Item) e.nextElement();
			Setting setting = (Setting) item2Setting.get(item);
			setting.value = getItemValue(item, setting);
		}
	}

	public Setting[] getSettings() {
		return settings;
	}

}
